import React, { PureComponent } from 'react';
import cx from 'classnames';
import PropTypes from 'prop-types';
import WPT from 'wpt';

import SortCeil from 'components/SortCeil';
import previewImage from 'modules/previewImage';
import uploadImage from 'modules/uploadImg';
import {
CDNURL, codeTranslate,     getVideoInfo, handleErr,
playVideo, waitCover} from 'modules/uploadVideo/core';

import wechatCheck from './wechatCheck';

import styles from './styles.less';

export default class Uploader extends PureComponent {
    static defaultProps = {
        IMAGE_LIMIT: 9,
        showNum: 9,
        onImageDelete: null,
        options: {
            isCut: false,
            openRemote: true,
            files: undefined,
        },
        imageMd5: false, // 是否开启图片md5校验，节省cdn空间
        getImageUrl: image => image,
        imageEnable: true,
        videoEnable: true,
        images: [],
        video: '',
        // videoCover: '',
        videoUrl: '',
        onVideoUpload: {},
        onVideoDelete: null,
        isVerify: false,
        imageUploaderClassName: '',
        imageClassName: '',
        videoUploaderClassName: '',
        videoPlayerClassName: '',
        maxVideoDuration: 15, // 视频最大时长，native上传不能超过15
        useNativeUploadVideo: false, // 在native环境下使用原生提供的上传方法
        // serverLocalIds: [],
        theme: '',
        title: '',
        subTitle: '',
        bType: 'sale', // 业务类型，默认为sale
        getQr: false,
        getVideoUrl: undefined,
        needNickname: true, // 是否需要店铺水印
        deleteWptWaterMark: false, // 是否删除微拍堂水印
        forbidDrag: false, // 是否禁止图片拖拽
    };

    static propTypes = {
        IMAGE_LIMIT: PropTypes.number,
        showNum: PropTypes.number,
        images: PropTypes.arrayOf(PropTypes.string),
        video: PropTypes.string,
        getImageUrl: PropTypes.func,
        onImageUpload: PropTypes.func.isRequired,
        onImageDelete: PropTypes.func,
        options: PropTypes.shape({
            isCut: PropTypes.bool,
            openRemote: PropTypes.bool,
            files: PropTypes.array,
        }),
        imageMd5: PropTypes.bool,
        imageEnable: PropTypes.bool,
        videoEnable: PropTypes.bool,
        onVideoUpload: PropTypes.shape({
            onStart: PropTypes.func,
            onProgress: PropTypes.func,
            onSuccess: PropTypes.func,
            onFail: PropTypes.func,
        }),
        maxVideoDuration: PropTypes.number,
        useNativeUploadVideo: PropTypes.bool,
        onVideoDelete: PropTypes.func,
        isVerify: PropTypes.bool,
        imageUploaderClassName: PropTypes.string,
        imageClassName: PropTypes.string,
        videoUploaderClassName: PropTypes.string,
        videoPlayerClassName: PropTypes.string,
        videoUrl: PropTypes.string,
        // videoCover: PropTypes.string,
        // serverLocalIds: PropTypes.array,
        theme: PropTypes.string,
        title: PropTypes.string,
        subTitle: PropTypes.string,
        getQr: PropTypes.bool,
        bType: PropTypes.string,
        getVideoUrl: PropTypes.func,
        needNickname: PropTypes.bool,
        deleteWptWaterMark: PropTypes.bool,
        forbidDrag: PropTypes.bool,
    };

    state = {
        videoCover: '',
        videoUrl: '',
    };

    componentDidMount() {
        if (this.props.video) {
            this.updateVideoInfo(this.props.video, this.props.videoUrl);
        }
    }

    componentWillReceiveProps(nextProps) {
        // IOS上传视频 用回调里的视频地址 不走下面的更新
        if (this.state.stopUpdate) {
            this.setState({
                stopUpdate: false,
            });
            return;
        }

        if (this.props.video !== nextProps.video && nextProps.video) {
            // 如果video发生变化，不需要复用videoUrl,videoCover
            this.updateVideoInfo(nextProps.video);
        }
    }

    updateVideoInfo = video => {
        const { videoCover: cover, videoUrl: url } = getVideoInfo(video, CDNURL);
        this.setState({
            videoCover: cover,
            videoUrl: url,
        });
    };

    previewImage = index => () => {
        const { images, getImageUrl } = this.props;
        const urls = images.map((image, i) => {
            if (getImageUrl) {
                return getImageUrl(image, i).replace('/w/240', '');
            }

            return image;
        });

        previewImage({
            current: urls[index],
            urls,
        });
    };

    uploadImage = () => {
        const {
            onImageUpload, images, options, IMAGE_LIMIT, imageMd5, getQr
        } = this.props;

        uploadImage(
            (serverImages, localImages, fileInfos) => {
                if (onImageUpload) {
                    onImageUpload(serverImages, localImages, fileInfos);
                }
            },
            {
                imgLimit: IMAGE_LIMIT - images.length,
                isCut: options.isCut,
                openRemote: options.openRemote,
                files: options.files,
                addMD5: imageMd5,
                getQr,
            }
        );
    };

    deleteImage = removedIndex => event => {
        event.stopPropagation();
        this.props.onImageDelete(removedIndex);
    };

    uploadVideo = () => {
        // 上传视频iOS内核提醒
        if (!wechatCheck()) {
            return;
        }

        if (!this.props.isVerify) {
            WPT.Modal.confirm('小视频上传,需要开通实名认证', {
                sure: {
                    btnName: '去实名认证',
                    msgClass: 'faq',
                    style: { color: '#AB3B3A' },
                    callback: () => {
                        WPT.showPage('/myVerify');
                    },
                },
                icon: { style: { color: '#AB3B3A' } },
                hasIcon: true,
            });
            return;
        }

        this.deleteVideo();

        const {
            onVideoUpload: {
                onStart, onProgress, onSuccess, onFail
            },
            maxVideoDuration,
            bType,
            useNativeUploadVideo,
            needNickname,
            deleteWptWaterMark
        } = this.props;

        if (WPT.os.wpt && WPT.os.wptAppVerison >= 361 && useNativeUploadVideo) {
            WPT.wptBridge.uploadVideo({
                bType,
                timeLimit: maxVideoDuration || 15,
                needNickname,
                deleteWptWaterMark,
                callback: res => {
                    if (res.code === 0) {
                        const key = res.data.videoKey;
                        this.setState({
                            videoUploading: true,
                            videoUploadingTransfer: true,
                            videoUploadingProgress: undefined,
                        });

                        // 392 之后 app返回 videoHasCompressed 通知 h5 视频是否转码
                        if ((WPT.os.ios && WPT.os.wptAppVerison < 392) || (WPT.os.wptAppVerison >= 392 && res.data.videoHasCompressed)) {
                            const cover = res.data.cover;
                            const videoUrl = res.data.videoUrl;
                            this.setState({
                                videoCover: cover,
                                videoUrl,
                                videoUploading: false,
                                videoUploadingTransfer: false,
                                stopUpdate: true,
                            });
                            if (onSuccess) {
                                onSuccess(key, res);
                            }
                        } else {
                            codeTranslate(key);
                            waitCover(
                                key,
                                CDNURL,
                                () => {
                                    const { videoCover, videoUrl } = getVideoInfo(key, CDNURL);
                                    this.setState({
                                        videoCover,
                                        videoUrl,
                                        videoUploading: false,
                                        videoUploadingTransfer: false,
                                    });

                                    if (onSuccess) {
                                        onSuccess(key, res);
                                    }
                                },
                                () => {
                                    WPT.Modal.tips('视频转码失败');
                                    this.deleteVideo();
                                }
                            );
                        }
                    } else {
                        this.deleteVideo();
                        WPT.Modal.alert('视频上传失败', { style: { color: '#AB3B3A' } });
                        if (onFail) {
                            onFail(res, '视频上传失败');
                        }
                    }
                },
            });
        } else {
            WPT.uploadVideo({
                bType,
                onStart: (...params) => {
                    this.setState({ videoUploading: true, videoUploadingProgress: 0 });

                    if (onStart) {
                        onStart(...params);
                    }
                },
                onProgress: (percent, ...params) => {
                    this.setState({ videoUploading: true, videoUploadingProgress: percent });
                    if (onProgress) {
                        onProgress(percent, ...params);
                    }
                },
                onSuccess: (key, result, ...params) => {
                    if (result && result.duration && result.duration < 1) {
                        WPT.Modal.tips('视频长度过短');
                        this.deleteVideo();
                        return;
                    }

                    // 转换视频
                    codeTranslate(key);
                    this.setState({ videoUploadingTransfer: true, videoUploadingProgress: undefined });

                    waitCover(
                        key,
                        CDNURL,
                        () => {
                            const { videoCover, videoUrl } = getVideoInfo(key, CDNURL);
                            this.setState({
                                videoCover,
                                videoUrl,
                                videoUploading: false,
                                videoUploadingTransfer: false,
                            });

                            if (onSuccess) {
                                onSuccess(key, result, ...params);
                            }
                        },
                        () => {
                            WPT.Modal.tips('视频转码失败');
                            this.deleteVideo();
                        }
                    );
                },
                onFail: (err, errTip, ...params) => {
                    if (onFail) {
                        onFail(err, errTip, ...params);
                    }

                    this.deleteVideo();
                    WPT.Modal.alert(handleErr(err, errTip, ...params), { style: { color: '#AB3B3A' } });
                },
            });
        }
    };

    playVideo = () => {
        if (this.videoPlayer && this.state.videoUrl) {
            const videoUrl = (this.props.getVideoUrl && this.props.getVideoUrl()) || this.state.videoUrl;
            playVideo(this.videoPlayer, videoUrl);
        }
    };

    deleteVideo = event => {
        if (event) {
            event.stopPropagation();
        }

        this.setState({
            videoCover: '',
            videoUrl: '',
            videoUploading: false,
            videoUploadingTransfer: false,
            videoUploadingProgress: null,
        });

        if (this.props.onVideoDelete) {
            this.props.onVideoDelete();
        }
    };

    inVideoUploading = () => this.state.videoUploading;

    renderVideoUploader = () => {
        const {
            videoEnable, video, isVerify, videoUploaderClassName, maxVideoDuration
        } = this.props;
        const { videoUploading, videoUploadingTransfer: inTransfer, videoUploadingProgress } = this.state;

        const inProgress = videoUploading && videoUploadingProgress >= 0;

        const videoLabel = maxVideoDuration ? `${maxVideoDuration}秒视频` : '15秒视频';

        if (!videoEnable) {
            return null;
        }

        if (video && !videoUploading) {
            return null;
        }

        return (
            <div
                className={cx(styles.uploadButton, !isVerify ? styles.disabled : '', videoUploaderClassName)}
                onClick={this.uploadVideo}
            >
                <i className={cx(styles.icon, 'wptFM icon-fm-video')} />
                <div>
                    {!videoUploading && videoLabel}
                    {inTransfer && '视频转码中'}
                    {inProgress && <span>上传中</span>}
                    {inProgress && <span>
                        {videoUploadingProgress}
%
                    </span>}
                </div>
            </div>
        );
    };

    renderVideoPlayer = () => {
        const { videoEnable, video, videoPlayerClassName } = this.props;
        const { videoCover, videoUploading } = this.state;

        if (!videoEnable) {
            return null;
        }

        if (!video || videoUploading) {
            return null;
        }

        return (
            <div
                ref={ref => {
                    this.videoPlayer = ref;
                }}
                className={cx(styles.videoPlayer, videoPlayerClassName)}
                style={{ backgroundImage: `url(${videoCover})` }}
                onClick={this.playVideo}
            >
                <span className={cx(styles.removeIcon, 'wptFM fi-stack')} onClick={this.deleteVideo}>
                    <i className="wptFM icon-fm-circle fi-stack-2x" />
                    <i className="wptFM icon-fm-addicon fi-color-fff fi-stack-1x" />
                </span>
                <span className={styles.playIcon} />
            </div>
        );
    };

    renderImageUploader = () => {
        const {
            imageEnable, images, IMAGE_LIMIT, imageUploaderClassName, title, subTitle, showNum
        } = this.props;

        if (!imageEnable || images.length >= IMAGE_LIMIT || images.length >= showNum) {
            return null;
        }

        return (
            <div onClick={this.uploadImage} className={cx(styles.uploadButton, imageUploaderClassName)}>
                <i className={cx(styles.icon, 'wptFM icon-fm-addImage', styles.scale)} />
                <div>{title || '添加图片'}</div>
                {!!subTitle && <div className={styles.subTitle}>{subTitle}</div>}
            </div>
        );
    };

    onResort = (newList = []) => {
        this.imgKeyPrev = Date.now();
        newList.forEach((item, index) => {
            this.props.onImageDelete(newList.length - 1 - index);
        });

        const serverImages = [];
        const localImages = [];
        newList.forEach(([serverId, localId]) => {
            serverImages.push(serverId);
            localImages.push(localId);
        });

        this.props.onImageUpload(serverImages, localImages);
    };

    render() {
        const {
            images, getImageUrl, imageEnable, imageClassName, IMAGE_LIMIT, theme, showNum, forbidDrag
        } = this.props;

        const isWptIos170 = WPT.os.wpt && $.os.ios && WPT.os.version.replace(/\./g, '') == 170;

        return (
            <div
                className={cx(styles.uploader, theme && styles[theme])}
                style={isWptIos170 ? { paddingBottom: '10px' } : {}}
            >
                {imageEnable
                    && images
                        .map((image, index) => {
                            const localImage = getImageUrl(image, index);
                            if (index + 1 > showNum) {
                                return null;
                            }
                            return (
                                <SortCeil
                                    key={`${this.imgKeyPrev}-${index}-${image}`}
                                    data={[image, localImage]}
                                    enable={!forbidDrag}
                                    onChange={this.onResort}
                                    onClick={this.previewImage(index)}
                                    className={cx(styles.image, imageClassName)}
                                >
                                    <div
                                        className={styles.coverImage}
                                        style={{ backgroundImage: `url(${localImage})` }}
                                    >
                                        <span
                                            className={cx(styles.removeIcon, 'wptFM fi-stack other-touch-action')}
                                            onClick={this.deleteImage(index)}
                                        >
                                            <i className="wptFM icon-fm-circle fi-stack-2x" />
                                            <i className="wptFM icon-fm-addicon fi-color-fff fi-stack-1x" />
                                        </span>
                                    </div>
                                </SortCeil>
                            );
                        })
                        .filter((_item, index) => index < IMAGE_LIMIT)}
                {this.renderImageUploader()}
                {this.renderVideoPlayer()}
                {this.renderVideoUploader()}
                {isWptIos170 && <div className={cx(styles.wptIosTip)}>此版本app原图上传有问题，建议使用公众号</div>}
            </div>
        );
    }
}
